home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Science / µSim 1.0b5 folder / source / Disasm.c < prev    next >
Encoding:
Text File  |  1994-09-01  |  11.0 KB  |  433 lines  |  [TEXT/MMCC]

  1. /*
  2. Copyright © 1993,1994 by Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware: you can copy, exchange, modify this
  5. code as you wish. You may include this code in any kind of application: freeware,
  6. shareware, or commercial, provided that full credits are given.
  7. You may not sell or distribute this code for profit.
  8. */
  9.  
  10. //#pragma load "MacDump"
  11.  
  12. #include    <stdlib.h>
  13.  
  14. #include    "UtilsSys7.h"
  15. #include    "Assembler.h"
  16. #include    "Disasm.h"
  17. #include    "Globals.h"
  18. #include    "Main.h"
  19. #include    "Microprogram_Ed.h"
  20. #include    "Input.h"
  21. #include    "Registers.h"
  22. #include    "TrackThumb.h"
  23. #include    "Conversions.h"
  24.  
  25. #if defined(FabSystem7orlater)
  26.  
  27. //#pragma segment Main
  28.  
  29. ControlHandle    disasmVScroll;
  30. static WindowPtr    curPosW;
  31. short    disasmLineHeight, disasmFromTop, disasmCWidMax;
  32.  
  33. static short *DisasmInstruction(short *inst, Ptr dest, ROpcDisasmPtr instrTbl, Size TblSize);
  34. static void ThumbActionProc(ControlHandle control, short value);
  35. static pascal void DisasmActionProc(ControlHandle control, short part);
  36. static int CompareFirstLast(const void *opc1, const void *opc2);
  37.  
  38. void DisasmHome(void)
  39. {
  40. SetCtlValue(disasmVScroll, GetCtlMin(disasmVScroll));
  41. InvalDisasm();
  42. }
  43.  
  44. void DisasmEnd(void)
  45. {
  46. SetCtlValue(disasmVScroll, GetCtlMax(disasmVScroll));
  47. InvalDisasm();
  48. }
  49.  
  50. void DisasmPgUp(void)
  51. {
  52. DisasmActionProc(disasmVScroll, inPageUp);
  53. }
  54.  
  55. void DisasmPgDn(void)
  56. {
  57. DisasmActionProc(disasmVScroll, inPageDown);
  58. }
  59.  
  60. /* DisasmInstruction: disassembles an instruction, returns a pointer to
  61. the next one. */
  62.  
  63. static short *DisasmInstruction(short *inst, Ptr dest, ROpcDisasmPtr instrTbl, Size TblSize)
  64. {
  65. Str15    tempS;
  66. register ROpcDisasmPtr    found;
  67. register char *tempcPtr;
  68. register short *newpos;
  69. register short    theOperand;
  70.  
  71. newpos = inst + 1;    /* at least two bytes per instruction */
  72. tempcPtr = (char *)bsearch(inst, &instrTbl->first, TblSize, sizeof(ROpcDisasm), CompareFirstLast);
  73. if (tempcPtr) {
  74.     tempcPtr -= ((char *)&instrTbl->first - (char *)instrTbl);
  75.     found = (ROpcDisasmPtr)tempcPtr;
  76.     *(OSType *)dest = found->instr;
  77.     if (found->class != kCLASS_16_0) {    /* there is an operand */
  78.         /* extra word ? */
  79.         theOperand = ((found->class == kCLASS_16_16) || (found->class == kCLASS_16_16_REL)) ?
  80.                         *newpos++ : *inst & (found->last - found->first);
  81.         switch (found->class) {    /* sign extensions for 12 & 11 bit operands */
  82.             case kCLASS_4_12:
  83.             case kCLASS_4_12_REL:
  84.                 theOperand <<= 4;
  85.                 theOperand >>= 4;
  86.                 break;
  87.             case kCLASS_5_11:
  88.                 theOperand <<= 5;
  89.                 theOperand >>= 5;
  90.                 break;
  91.             }
  92.         if (found->class == kCLASS_4_12)
  93.             ShortToHexString(theOperand, tempS);
  94.         else
  95.             MyNumToString(theOperand, tempS);
  96.         tempcPtr = dest + 5;
  97.         if (found->class == kCLASS_4_12)    /* hex value */
  98.             *tempcPtr++ = '$';
  99.         if (found->class >= kCLASS_16_16_REL) {    /* relative jumps */
  100.             *tempcPtr++ = '*';
  101.             if (theOperand > 0)    /* wanna a plus sign before positive values */
  102.                 *tempcPtr++ = '+';
  103.             }
  104.         BlockMoveData(&tempS[1], tempcPtr, tempS[0]);
  105.         tempcPtr += tempS[0];
  106.         if (found->class >= kCLASS_16_16_REL) {    /* relative jumps */
  107.             *tempcPtr++ = ' ';
  108.             *tempcPtr++ = '(';
  109.             *tempcPtr++ = '$';
  110.             tempcPtr = ShortToHexText(PTR2MEMWORD(newpos) + theOperand, tempcPtr);
  111.             *tempcPtr++ = ')';
  112.             }
  113.         }
  114.     }
  115. else {
  116.     *(OSType *)dest = 'ILL*';
  117.     }
  118. return newpos;
  119. }
  120.  
  121.  
  122. /* Activate_Disasm: handles activate events */
  123.  
  124. void Activate_Disasm(WindowPtr w, Boolean becomingActive)
  125. {
  126. Rect    growRect;
  127.  
  128. /* the growbox needs to be redrawn on activation: */
  129. growRect = w->portRect;
  130. /* adjust for the scrollbars */
  131. growRect.top = growRect.bottom - kScrollbarAdjust + 1;
  132. growRect.left = growRect.right - kScrollbarAdjust + 1;
  133. if (becomingActive) {
  134.     InvalRect(&growRect);    /* we cannot avoid grow box flicker */
  135.     if ((*disasmVScroll)->contrlVis == 0) {
  136.         ShowControl(disasmVScroll);
  137.         ValidRect(&(*disasmVScroll)->contrlRect);
  138.         }
  139.     }
  140. else {
  141. /* the control must be redrawn on deactivation: */
  142.     HideControl(disasmVScroll);
  143.     InvalRect(&growRect);
  144.     }
  145. } /*Activate*/
  146.  
  147. /* Grow_Disasm: handles resizing */
  148.  
  149. void Grow_Disasm(WindowPtr w, EventRecord *event)
  150. {
  151. Rect    tempRect, updateRect;
  152. register long    growResult;
  153.  
  154. tempRect.right = tempRect.left = PRCT_R(w) + 1;
  155. tempRect.bottom = 0x7FFF;        /* set up limiting values */
  156. tempRect.top = kMinDocDim;
  157. updateRect = w->portRect;
  158. updateRect.top = updateRect.bottom - kScrollbarAdjust;
  159. /* see if it really changed size */
  160. if (growResult = GrowWindow(w, event->where, &tempRect)) {
  161.     SizeWindow(w, LoWrd(growResult),
  162.                 (HiWrd(growResult) / disasmLineHeight) * disasmLineHeight, true);
  163.     SizeControl(disasmVScroll, kScrollbarWidth, PRCT_B(w) - PRCT_T(w) - 13);
  164.     if (HiWrd(growResult) > updateRect.bottom)
  165.         /* enlarged */
  166.         InvalRect(&updateRect);
  167.     else /* reduced */ {
  168.         updateRect.bottom = PRCT_B(w);
  169.         updateRect.right = PRCT_R(w);
  170.         updateRect.top = updateRect.bottom - kScrollbarAdjust + 1;
  171.         updateRect.left = updateRect.right - kScrollbarAdjust + 1;
  172.         InvalRect(&updateRect);
  173.         }
  174.     ValidRect(&(*disasmVScroll)->contrlRect);
  175.     SetupDisasmCtlMax(disasmVScroll);
  176.     }
  177. }
  178.  
  179. /* Update_Disasm: handles window updates. */
  180.  
  181. void Update_Disasm(WindowPtr w)
  182. {
  183. Rect    growRect;
  184. register RgnHandle    oldClip;
  185.  
  186. if (EmptyRgn(w->visRgn) == false) {    /* draw if updating needs to be done */
  187.     DrawDisasm(w);
  188.     oldClip = NewRgn();
  189.     GetClip(oldClip);
  190.     growRect = w->portRect;
  191.     growRect.left = growRect.right - kScrollbarAdjust;
  192.     ClipRect(&growRect);
  193.     DrawGrowIcon(w);
  194.     SetClip(oldClip);
  195.     DisposeRgn(oldClip);
  196.     UpdtControl(w, w->visRgn);
  197.     }
  198. }
  199.  
  200. /* Do_Disasm: we handle mouse clicks in scrollbars */
  201.  
  202. void Do_Disasm(WindowPtr w, EventRecord *event)
  203. {
  204. enum {
  205. kCurPosWindow = 128
  206. };
  207.  
  208. Rect    tempRect;
  209. GrafPtr    savePort;
  210. ControlHandle    control;
  211. Point    mouse;
  212. register short    part;
  213.  
  214. mouse = event->where;        /* get the click position */
  215. GlobalToLocal(&mouse);
  216. /* see if we are in the disasm area; if so, we won’t check the controls */
  217. tempRect = w->portRect;
  218. tempRect.right -= kScrollbarAdjust;
  219. if (PtInRect(mouse, &tempRect)) {
  220.     /* handle editing click */
  221. /*    if ((offset = mouse.h - disasmCWidMax * 6 - kDIST_FROMLEFT) >= 0)
  222.         if ((offset /= disasmCWidMax) % 5 != 4) {
  223.             tempRect.top = (mouse.v /= dumpLineHeight) * dumpLineHeight;
  224.             tempRect.left = ((offset / 5) * 5) * dumpCWidMax + dumpCWidMax * 6 + kDIST_FROMLEFT;
  225.             tempRect.bottom = tempRect.top + dumpLineHeight;
  226.             tempRect.right = tempRect.left + (dumpCWidMax << 2);
  227.             if (TrackObject(&tempRect)) {
  228.                 clickAddr = ((unsigned long)(GetCtlValue(dumpVScroll) + mouse.v) << 4)
  229.                             + ((offset / 5) << 1);
  230.                 if (DoEditDump((short *)(mMemory + clickAddr), clickAddr >> 1))
  231.                     DrawDump();
  232.                 UnloadSeg(DoEditDump);
  233.                 }
  234.             }*/
  235.     }
  236. else {
  237.     part = FindControl(mouse, w, &control);
  238.     switch ( part ) {
  239.         case 0:        /* do nothing for viewRect case */
  240.             break;
  241.         case inThumb:
  242.             GetPort(&savePort);
  243.             SetPort(curPosW = GetNewWindow(kCurPosWindow, nil, (WindowPtr)-1L));
  244.             TextMode(srcCopy);
  245.             TextFont(monaco);
  246.             TextSize(9);
  247.             SetPort(savePort);
  248.             savePort = (GrafPtr)LMGetGhostWindow();
  249.             LMSetGhostWindow((WindowPeek)curPosW);
  250.             ShowWindow(curPosW);
  251.             part = TrackThumb(control, mouse, ThumbActionProc);
  252.             DisposeWindow(curPosW);
  253.             LMSetGhostWindow((WindowPeek)savePort);
  254.             InvalDisasm();
  255.             break;
  256.         default:    /* clicked in an arrow, so track & scroll */
  257.             {
  258.             ControlActionUPP DisasmActionProcUPP = NewControlActionProc(DisasmActionProc);
  259.  
  260.             part = TrackControl(control, mouse, DisasmActionProcUPP);
  261.             if (DisasmActionProcUPP)
  262.                 DisposeRoutineDescriptor(DisasmActionProcUPP);
  263.             }
  264.             break;
  265.         }
  266.     }
  267. }
  268.  
  269. /* ThumbActionProc: continuously called while we drag the scroll box */
  270.  
  271. static void ThumbActionProc(ControlHandle , short value)
  272. {
  273. Str15    tempS;
  274. GrafPtr    savePort;
  275.  
  276. ShortToHexString(value << 1, tempS);
  277. GetPort(&savePort);
  278. SetPort(curPosW);
  279. MoveTo(kDIST_FROMLEFT,12);
  280. DrawString(tempS);
  281. SetPort(savePort);
  282. }
  283.  
  284. /* DisasmActionProc: called when we hold mouse button down in some
  285. parts of the scroll bar. */
  286.  
  287. static pascal void DisasmActionProc(ControlHandle control, short part)
  288. {
  289. register WindowPtr    w;
  290. register long    templong = 0L;
  291. register short    amount, oldAmount;
  292.  
  293. if ( part ) {        /* if it was actually in the control */
  294.     w = (*control)->contrlOwner;
  295.     switch ( part ) {
  296.         case inUpButton:
  297.             amount = -1;
  298.             break;
  299.         case inDownButton:
  300.             amount = 1;
  301.             break;
  302.         case inPageUp:
  303.             amount = (PRCT_T(w) - PRCT_B(w)) / (disasmLineHeight * 2) + 1;
  304.             break;
  305.         case inPageDown:
  306.             amount = (PRCT_B(w) - PRCT_T(w)) / (disasmLineHeight * 2) - 1;
  307.             break;
  308.         }
  309.     SetCtlValue(control, (oldAmount = GetCtlValue(control)) + amount);
  310.     if (oldAmount != GetCtlValue(control))
  311.         DrawDisasm(w);
  312.     }
  313. } /* DisasmActionProc */
  314.  
  315. /* DrawDisasm: redraws the entire Disassembler window */
  316.  
  317. void DrawDisasm(WindowPtr w)
  318. {
  319. Str27    disassembledText;
  320. Rect    tempRect, ToBeInverted;
  321. GrafPtr    savePort;
  322. Handle    tH;
  323. Point    tempPoint;
  324. short *addr;
  325. register long *clrptr;
  326. register short *textPtr;
  327. register long    spaces = 0L;
  328. short    j, HilitePC;
  329. SignedByte    savedState;
  330.  
  331. GetPort(&savePort);
  332. SetPort(w);
  333. savedState = WantThisHandleSafe(tH = Get1Resource(krInstructions, kOPCODES));
  334. tempRect = w->portRect;
  335. tempRect.bottom += disasmLineHeight;
  336. spaces = GetCtlValue(disasmVScroll);
  337. addr = (short *)&gMMemory[spaces << 2];
  338. for(tempPoint.h = kDIST_FROMLEFT, j = disasmFromTop;
  339.     tempPoint.v = j, PtInRect(tempPoint, &tempRect);
  340.     j += disasmLineHeight) {
  341.  
  342.     MoveTo(PRCT_L(w) + kDIST_FROMLEFT, j);
  343.     clrptr = (long *)&disassembledText;
  344.     spaces = '    ';
  345.     *clrptr++ = spaces;
  346.     *clrptr++ = spaces;
  347.     *clrptr++ = spaces;
  348.     *clrptr++ = spaces;
  349.     *clrptr++ = spaces;
  350.     *clrptr++ = spaces;
  351.     *clrptr = spaces;
  352.     textPtr = (short *)ShortToHexText(HilitePC = PTR2MEMWORD(addr), (Ptr)&disassembledText);
  353.     *textPtr++ = ': ';
  354.     addr = DisasmInstruction(addr, (Ptr)textPtr, (ROpcDisasmPtr)((*tH) + 2), *(unsigned short *)*tH + 1);
  355.  
  356.     DrawText(&disassembledText, 0L, 28L);
  357.     if (HilitePC == gRegs[kREG_PC]) {
  358.         ToBeInverted.top = j - disasmLineHeight + 1;
  359.         ToBeInverted.left = PRCT_L(w) + kDIST_FROMLEFT;
  360.         ToBeInverted.bottom = j + 1;
  361.         ToBeInverted.right = ToBeInverted.left + disasmCWidMax * kMaxCharsInOneDisasmLine;
  362.         LMSetHiliteMode(LMGetHiliteMode() & 0x7F);
  363.         InvertRect(&ToBeInverted);
  364.         }
  365.     }
  366. HSetState(tH, savedState);
  367. SetPort(savePort);
  368. }
  369.  
  370. /* SetupDisasmCtlMax: sets up the CtlMax value of our scroll bar */
  371.  
  372. void SetupDisasmCtlMax(ControlHandle theControl)
  373. {
  374. enum {
  375. kAdjustForPleasantGrow = 3
  376. };
  377.  
  378. register WindowPtr    wind;
  379. register short    newmax;
  380.  
  381. wind = (*theControl)->contrlOwner;
  382. newmax = 32767 - (PRCT_B(wind) - PRCT_T(wind) - kAdjustForPleasantGrow) / (disasmLineHeight << 1);
  383. if (newmax != GetCtlMax(theControl)) {
  384.     SetCtlMax(theControl, newmax);
  385.     InvalDisasm();
  386.     }
  387. }
  388.  
  389. /* InvalDisasm: invalidates the entire window contents
  390. (excluding the scrollbar) */
  391.  
  392. void InvalDisasm(void)
  393. {
  394. Rect    tempRect;
  395. GrafPtr    savePort;
  396.  
  397. GetPort(&savePort);
  398. SetPort(gWPtr_Disasm);
  399. tempRect = gWPtr_Disasm->portRect;
  400. tempRect.right -= kScrollbarWidth;
  401. InvalRect(&tempRect);
  402. SetPort(savePort);
  403. }
  404.  
  405. /* procedure called when closing the Disasm window */
  406.  
  407. void CloseDisasm(WindowPtr w)
  408. {
  409. DoCloseWindow(w, kMItem_Disasm);
  410. }
  411.  
  412. static int CompareFirstLast(const void *opc1, const void *opc2)
  413. {
  414. register unsigned short *tempP = (unsigned short *)opc2;
  415. unsigned short    d1, d2;
  416. int    d0;
  417.  
  418. d2 = *(short *)opc1;
  419. d0 = d2;
  420. d1 = *tempP++;
  421. if ((d0 -= d1) > 0) {
  422.     d0 = d2;
  423.     d1 = *tempP;
  424.     if ((d0 -= d1) <= 0)
  425.         d0 = 0;
  426.     }
  427.  
  428. return d0;
  429. }
  430.  
  431. #endif
  432.  
  433.